package com.juyu.miliao.api.dao.redis;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.juyu.miliao.api.dao.mysql.DynamicInfoDao;
import com.juyu.miliao.api.dao.mysql.DynamicLikeInfoDao;
import com.juyu.miliao.api.dao.mysql.DynamicSourceInfoDao;
import com.juyu.miliao.api.domain.*;

import com.juyu.miliao.api.domain.dto.DynamicInfoDTO;
import com.juyu.miliao.api.domain.dto.DynamicReportInfoDTO;
import com.juyu.miliao.api.domain.vo.DynamicDetailInfoVo;
import com.juyu.miliao.api.domain.vo.DynamicInfoVo;
import com.juyu.miliao.api.domain.vo.DynamicSourceInfoVO;
import com.juyu.miliao.common.constant.DynamicInfoRedisKey;
import com.juyu.miliao.common.exception.ConsumeRuntimeException;
import com.juyu.miliao.common.util.DateUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 社区动态redis dao
 *
 * @author xuanqicheng
 * @create 2019-21-10:02
 */
@Repository
public class DynamicInfoRedisDao {

    @Autowired
    private DynamicInfoDao dynamicInfoDao;

    @Autowired
    private DynamicSourceInfoDao dynamicSourceInfoDao;

    @Autowired
    private DynamicLikeInfoDao dynamicLikeInfoDao;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private FollowRedisDao followRedisDao;


    /**
     * 添加动态信息
     *
     * @param dynamicInfo
     */
    public void addDynamciInfo(DynamicInfo dynamicInfo) {

        dynamicInfoDao.addDynamciInfo(dynamicInfo);

        deleteListCache(dynamicInfo);
    }


    /**
     * 删除动态缓存
     */
    public void deleteListCache(DynamicInfo dynamicInfo) {

        String key = DynamicInfoRedisKey.QuertDynamicInfoKeySet.REDIS_KEY.getKeyFormat();

        String deleteDetailKey = DynamicInfoRedisKey.DynamicInfoByDynamicId.REDIS_KEY.getKeyFormat(dynamicInfo.getDynamicId());

        Set<String> deleteSet = stringRedisTemplate.opsForSet().members(key);


        String dynamicInfoByUserIdKey = DynamicInfoRedisKey.DynamicInfoListByUserIdAndPage.REDIS_KEY
                .getKeyFormat(dynamicInfo.getUserId());

        if (deleteSet.size() > 0) {
            deleteSet.add(dynamicInfoByUserIdKey);
        } else {
            deleteSet = new HashSet<>();
            deleteSet.add(dynamicInfoByUserIdKey);
        }

        deleteSet.add(deleteDetailKey);

        List<Follow> followList = followRedisDao.getFansById(dynamicInfo.getUserId(), 0, 0);

        if (followList.size() > 0) {

            for (Follow follow : followList) {

                String followKey = DynamicInfoRedisKey.DynamicInfoListByFollowUser.REDIS_KEY.getKeyFormat(follow.getFollowUserId());

                deleteSet.add(followKey);
            }

        }

        stringRedisTemplate.delete(deleteSet);


    }

    /**
     * 设置查询key的缓存
     *
     * @param queryDynamicKey
     */
    private void setQueryDynamicKey(String queryDynamicKey) {

        String key = DynamicInfoRedisKey.QuertDynamicInfoKeySet.REDIS_KEY.getKeyFormat();

        stringRedisTemplate.opsForSet().add(key, queryDynamicKey);
    }

    /**
     * 获取动态缓存信息
     *
     * @param startNum
     * @param pageSize
     * @return
     */
    public List<DynamicInfoVo> getDynamicInfoList(Integer startNum, Integer pageSize) {

        List<DynamicInfoVo> list;

        String key = DynamicInfoRedisKey.DynamicInfoListByPage.REDIS_KEY.getKeyFormat(startNum, pageSize);

        String temp = stringRedisTemplate.opsForValue().get(key);

        if (!StringUtils.isEmpty(temp)) {
            list = JSONArray.parseArray(temp, DynamicInfoVo.class);
        } else {
            list = dynamicInfoDao.selectDynamicListPage(startNum, pageSize);
            if (list.size() > 0) {
                for (DynamicInfoVo obj : list) {
                    List<DynamicSourceInfoVO> dynamicSourceUrls = getDynamicSourceInfoByDynamicId(obj.getDynamicId());

                    obj.setDynamicSourceUrls(dynamicSourceUrls);

                }

                stringRedisTemplate.opsForValue().set(key, JSONObject.toJSONString(list), 30, TimeUnit.MINUTES);
            }

        }

        setQueryDynamicKey(key);

        return list;
    }


    /**
     * 添加动态资源
     *
     * @param dynamicId
     * @param dynamicInfoDTO
     */
    public void addDynamicSourceInfo(Long dynamicId, DynamicInfoDTO dynamicInfoDTO) {
        List<String> sourceList = dynamicInfoDTO.getDynamicSourceUrls();
        if (sourceList.size() > 0) {
            List<DynamicSourceInfo> dynamicSourceInfos = new ArrayList<>();
            List<DynamicSourceInfoVO> dynamicSourceInfoVOS = new ArrayList<>();
            for (String url : sourceList) {
                if (!StringUtils.isEmpty(url)) {
                    DynamicSourceInfo dynamicSourceInfo = new DynamicSourceInfo()
                            .setDynamicId(dynamicId)
                            .setDynamicSourceUrl(url)
                            .setVideoImgUrl(dynamicInfoDTO.getVideoImgUrl())
                            .setWidth(dynamicInfoDTO.getWidth())
                            .setHeight(dynamicInfoDTO.getHeight())
                            .setVideoTime(dynamicInfoDTO.getVideoTime());

                    DynamicSourceInfoVO dynamicSourceInfoVO = new DynamicSourceInfoVO();

                    BeanUtils.copyProperties(dynamicSourceInfo, dynamicSourceInfoVO);

                    if (StringUtils.isEmpty(dynamicSourceInfoVO.getVideoTime())) {
                        String time = DateUtil.secToTime(0);
                        dynamicSourceInfoVO.setVideoTime(time);
                    } else {
                        String time = DateUtil.secToTime(Integer.parseInt(dynamicSourceInfoVO.getVideoTime()));
                        dynamicSourceInfoVO.setVideoTime(time);
                    }
                    dynamicSourceInfos.add(dynamicSourceInfo);

                    dynamicSourceInfoVOS.add(dynamicSourceInfoVO);
                }

            }

            dynamicSourceInfoDao.addDynamicSourceInfos(dynamicSourceInfos);

            if (dynamicSourceInfoVOS.size() > 0) {
                setDynamicSourceInfoByDynamicId(dynamicId, dynamicSourceInfoVOS);
            }

        }
    }

    /**
     * 根据动态id,获取动态资源
     *
     * @param dynamicId
     * @return
     */
    public List<DynamicSourceInfoVO> getDynamicSourceInfoByDynamicId(long dynamicId) {
        String key = DynamicInfoRedisKey.DynamicSourceInfoByDynamicId.REDIS_KEY.getKeyFormat(dynamicId);
        String temp = stringRedisTemplate.opsForValue().get(key);
        if (!StringUtils.isEmpty(temp)) {
            return JSONArray.parseArray(temp, DynamicSourceInfoVO.class);
        } else {


            List<DynamicSourceInfoVO> list = dynamicSourceInfoDao.selectDynamicSourcesByDynamicId(dynamicId);

            for (DynamicSourceInfoVO obj : list) {
                if (!StringUtils.isEmpty(obj.getVideoTime())) {
                    String time = DateUtil.secToTime(Integer.parseInt(obj.getVideoTime()));
                    obj.setVideoTime(time);
                } else {
                    String time = DateUtil.secToTime(0);
                    obj.setVideoTime(time);
                }
            }


            if (list.size() > 0) {
                stringRedisTemplate.opsForValue().set(key, JSONObject.toJSONString(list), 30, TimeUnit.MINUTES);
            }

            return list;
        }

    }

    /**
     * 设置资源缓存
     *
     * @param dynamicId
     * @param dynamicSourceUrls
     */
    private void setDynamicSourceInfoByDynamicId(long dynamicId, List<DynamicSourceInfoVO> dynamicSourceUrls) {
        String key = DynamicInfoRedisKey.DynamicSourceInfoByDynamicId.REDIS_KEY.getKeyFormat(dynamicId);
        stringRedisTemplate.opsForValue().set(key, JSONObject.toJSONString(dynamicSourceUrls), 30,
                TimeUnit.MINUTES);
    }


    /**
     * 取消点赞
     *
     * @param obj
     */
    public void subtractionLikeInfo(DynamicLikeInfo obj) {

        dynamicLikeInfoDao.deleteDynamicLikeInfo(obj);

        String key = DynamicInfoRedisKey.DynamicLikeInfoByDynamicId.REDIS_KEY.getKeyFormat(obj.getDynamicId());
        String likeKey = DynamicInfoRedisKey.DynamicLikeInfoByDynamicId.USER_INFO
                .getUserKeyFormat(obj.getDynamicId(), obj.getUserId());
        Set<String> deleteSet = new HashSet<>();
        deleteSet.add(key);
        deleteSet.add(likeKey);

        stringRedisTemplate.delete(deleteSet);
    }

    /**
     * 添加点赞
     *
     * @param obj
     */
    public void addLikeInfo(DynamicLikeInfo obj) {
        dynamicLikeInfoDao.addDynamicLikeInfo(obj);

        Set<String> deleteSet = new HashSet<>();

        String key = DynamicInfoRedisKey.DynamicLikeInfoByDynamicId.REDIS_KEY.getKeyFormat(obj.getDynamicId());

        deleteSet.add(key);

        stringRedisTemplate.delete(deleteSet);


    }

    /**
     * 根据动态id,获取点赞数
     *
     * @param dynamicId
     * @return
     */
    public int getDynamicLikeByDynamicId(Long dynamicId) {
        String key = DynamicInfoRedisKey.DynamicLikeInfoByDynamicId.REDIS_KEY.getKeyFormat(dynamicId);
        String temp = stringRedisTemplate.opsForValue().get(key);
        if (!StringUtils.isEmpty(temp)) {

            return Integer.parseInt(temp);

        } else {
            int number = dynamicLikeInfoDao.selectDynamicLikeCount(dynamicId);
            if (number > 0) {
                stringRedisTemplate.opsForValue().set(key, Integer.toString(number), 30, TimeUnit.MINUTES);
            }


            return number;
        }
    }

    public boolean checkUserLikeDynamicInfoByUserId(long userId, long dynamicId) {

        DynamicLikeInfo obj = getUserLikeDynamicInfoByUserId(userId, dynamicId);
        if (obj == null) {
            return false;
        } else {
            return true;
        }
    }

    private DynamicLikeInfo getUserLikeDynamicInfoByUserId(long userId, long dynamicId) {

        String key = DynamicInfoRedisKey.DynamicLikeInfoByDynamicId.USER_INFO.getUserKeyFormat(dynamicId, userId);

        String temp = stringRedisTemplate.opsForValue().get(key);

        if (!StringUtils.isEmpty(temp)) {

            DynamicLikeInfo obj = JSONObject.parseObject(temp, DynamicLikeInfo.class);

            return obj;
        } else {
            DynamicLikeInfo obj = dynamicLikeInfoDao.selectDynamicLikeByDynamicAndUserId(userId, dynamicId);

            if (obj != null) {
                stringRedisTemplate.opsForValue().set(key, JSONObject.toJSONString(obj), 30, TimeUnit.MINUTES);
            }
            return obj;
        }


    }

    /**
     * 根据动态id,获取动态详情
     *
     * @param dynamicId
     * @return
     */
    public DynamicDetailInfoVo getDynamicInfoById(long dynamicId) {

        String key = DynamicInfoRedisKey.DynamicInfoByDynamicId.REDIS_KEY.getKeyFormat(dynamicId);

        String temp = stringRedisTemplate.opsForValue().get(key);

        if (!StringUtils.isEmpty(temp)) {

            DynamicDetailInfoVo dynamicDetailInfoVo = JSONObject.parseObject(temp, DynamicDetailInfoVo.class);

            return dynamicDetailInfoVo;
        } else {
            DynamicDetailInfoVo dynamicDetailInfoVo = dynamicInfoDao.getDynamicInfoById(dynamicId);

            if (dynamicDetailInfoVo != null) {

                List<DynamicSourceInfoVO> dynamicSourceUrls = getDynamicSourceInfoByDynamicId(dynamicDetailInfoVo.getDynamicId());

                dynamicDetailInfoVo.setDynamicSourceUrls(dynamicSourceUrls);

                stringRedisTemplate.opsForValue().set(key, JSONObject.toJSONString(dynamicDetailInfoVo), 30,
                        TimeUnit.MINUTES);
            }
            return dynamicDetailInfoVo;
        }

    }

    /**
     * 添加评论礼物
     *
     * @param dynamicGiftInfo
     */
    public void saveDynamicGiftInfo(DynamicGiftInfo dynamicGiftInfo) {
        dynamicInfoDao.saveDynamicGiftInfo(dynamicGiftInfo);
        deleteDynamicGiftInfo(dynamicGiftInfo.getDynamicId());
    }

    /**
     * 删除动态礼物列表
     *
     * @param dynamicId
     */
    private void deleteDynamicGiftInfo(long dynamicId) {

        Set<String> keySet = new HashSet<>();

        String key = DynamicInfoRedisKey.DynamicGiftInfoByDynamicId.REDIS_KEY.getKeyFormat(dynamicId);

        keySet.add(key);

        String userKey = DynamicInfoRedisKey.DynamicGiftInfoUserIdByDynamicId.REDIS_KEY.getKeyFormat(dynamicId);

        keySet.add(userKey);

        stringRedisTemplate.delete(keySet);
    }

    /**
     * 根据动态id,查询动态礼物列表
     *
     * @param dynamicId
     * @return
     */
    public List<DynamicGiftInfo> getDynamicGiftList(long dynamicId) {
        String key = DynamicInfoRedisKey.DynamicGiftInfoByDynamicId.REDIS_KEY.getKeyFormat(dynamicId);
        String temp = stringRedisTemplate.opsForValue().get(key);
        if (!StringUtils.isEmpty(temp)) {
            return JSONArray.parseArray(temp, DynamicGiftInfo.class);
        } else {
            List<DynamicGiftInfo> dynamicGiftInfoList = dynamicInfoDao.getDynamicGiftListByDynamicId(dynamicId);
            if (dynamicGiftInfoList.size() > 0) {
                stringRedisTemplate.opsForValue().set(key, JSONObject.toJSONString(dynamicGiftInfoList), 30, TimeUnit.MINUTES);
            }
            return dynamicGiftInfoList;
        }
    }

    /**
     * 根据动态id,查询送礼物的人，去重
     *
     * @param dynamicId
     * @return
     */
    public List<Long> getDynamicGiftUserList(long dynamicId) {
        String key = DynamicInfoRedisKey.DynamicGiftInfoUserIdByDynamicId.REDIS_KEY.getKeyFormat(dynamicId);
        String temp = stringRedisTemplate.opsForValue().get(key);
        if (!StringUtils.isEmpty(temp)) {
            return JSONArray.parseArray(temp, Long.class);
        } else {
            List<Long> userList = dynamicInfoDao.getDynamicGiftUserList(dynamicId);
            if (userList.size() > 0) {
                stringRedisTemplate.opsForValue().set(key, JSONObject.toJSONString(userList), 30, TimeUnit.MINUTES);
            }

            return userList;
        }
    }

    /**
     * 根据用户id 查询动态信息
     *
     * @param userId
     * @param startNum
     * @param pageSize
     * @return
     */
    public List<DynamicInfoVo> getDynamicInfoListByUserId(long userId, int startNum, Integer pageSize) {
        List<DynamicInfoVo> list;

        String key = DynamicInfoRedisKey.DynamicInfoListByUserIdAndPage.REDIS_KEY.getKeyFormat(userId);

        String hashKey = DynamicInfoRedisKey.DynamicInfoListByUserIdAndPage.HASH_REDIS_KEY.getHashKey(startNum, pageSize);

        String temp = (String) stringRedisTemplate.opsForHash().get(key, hashKey);

        if (!StringUtils.isEmpty(temp)) {

            list = JSONArray.parseArray(temp, DynamicInfoVo.class);

        } else {

            list = dynamicInfoDao.selectDynamicListUserIdPage(userId, startNum, pageSize);

            if (list.size() > 0) {

                for (DynamicInfoVo obj : list) {

                    List<DynamicSourceInfoVO> dynamicSourceUrls = getDynamicSourceInfoByDynamicId(obj.getDynamicId());

                    obj.setDynamicSourceUrls(dynamicSourceUrls);

                }

                stringRedisTemplate.opsForHash().put(key, hashKey, JSONObject.toJSONString(list));

                stringRedisTemplate.expire(key, 40, TimeUnit.MINUTES);
            }

        }

        return list;

    }

    public void setDynamicShare(Long dynamicId) {
        DynamicShareInfo dynamicShareInfo = dynamicInfoDao.getDynamicShareByDynamicId(dynamicId);
        if (dynamicShareInfo == null) {
            dynamicInfoDao.addDynamicShare(dynamicId);

        } else {
            dynamicInfoDao.updateShareNumber(dynamicId);
        }

        String key = DynamicInfoRedisKey.DynamicInfoShareByDynamicId.REDIS_KEY.getKeyFormat(dynamicId);
        stringRedisTemplate.delete(key);

    }

    public int getDynamicShare(Long dynamicId) {

        String key = DynamicInfoRedisKey.DynamicInfoShareByDynamicId.REDIS_KEY.getKeyFormat(dynamicId);

        String temp = stringRedisTemplate.opsForValue().get(key);

        if (!StringUtils.isEmpty(temp)) {

            return Integer.parseInt(temp);

        } else {
            DynamicShareInfo dynamicShareInfo = dynamicInfoDao.getDynamicShareByDynamicId(dynamicId);
            if (dynamicShareInfo != null && dynamicShareInfo.getShareNum() != null) {
                stringRedisTemplate.opsForValue().set(key, dynamicShareInfo.getShareNum() + "", 40, TimeUnit.MINUTES);
                return dynamicShareInfo.getShareNum();
            } else {
                stringRedisTemplate.opsForValue().set(key, "0", 40, TimeUnit.MINUTES);
                return 0;
            }

        }
    }

    public void setReport(DynamicReportInfoDTO obj) {
        DynamicReportInfo entity = dynamicInfoDao.getReportByDynamicIdAndUserId(obj);
        if (entity != null) {
            throw new ConsumeRuntimeException("已经举报过，请勿重复举报");
        }
        DynamicReportInfo dynamicReportInfo = new DynamicReportInfo();
        BeanUtils.copyProperties(obj, dynamicReportInfo);
        dynamicInfoDao.addDynamicReportInfo(dynamicReportInfo);
    }

    public List<DynamicInfoVo> getFollowDynamicInfoList(long userId, List<Long> followUserList, int startNum, Integer pageSize) {

        if (followUserList.size() > 0) {
            String key = DynamicInfoRedisKey.DynamicInfoListByFollowUser.REDIS_KEY.getKeyFormat(userId);

            String hashKey = DynamicInfoRedisKey.DynamicInfoListByFollowUser.HASH_REDIS_KEY.getHashKey(startNum, pageSize);

            String temp = (String) stringRedisTemplate.opsForHash().get(key, hashKey);

            if (!StringUtils.isEmpty(temp)) {

                List<DynamicInfoVo> list = JSONArray.parseArray(temp, DynamicInfoVo.class);

                return list;
            } else {

                List<DynamicInfoVo> list = dynamicInfoDao.selectDynamicListFollowPage(followUserList, startNum, pageSize);

                if (list.size() > 0) {
                    for (DynamicInfoVo obj : list) {

                        List<DynamicSourceInfoVO> dynamicSourceUrls = getDynamicSourceInfoByDynamicId(obj.getDynamicId());

                        obj.setDynamicSourceUrls(dynamicSourceUrls);

                    }

                    stringRedisTemplate.opsForHash().put(key, hashKey, JSONObject.toJSONString(list));

                    stringRedisTemplate.expire(key, 10, TimeUnit.MINUTES);
                }

                return list;
            }

        } else {

            return new ArrayList<>();
        }
    }

    /**
     * 删除动态
     *
     * @param dynamicId
     */
    public void deleteDyanmicInfo(long dynamicId) {

        DynamicDetailInfoVo obj = dynamicInfoDao.getDynamicInfoById(dynamicId);

        dynamicInfoDao.deleteDynamicInfo(dynamicId);

        DynamicInfo dynamicInfo = new DynamicInfo();

        if (obj != null) {
            BeanUtils.copyProperties(obj, dynamicInfo);

            deleteListCache(dynamicInfo);
        }

    }


}
